home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
fax
/
src
/
port
/
generic
/
GCC-PATCH
next >
Wrap
Text File
|
1994-08-01
|
11KB
|
321 lines
Fri Apr 9 20:03:38 1993 Jim Wilson (wilson@wookumz.gnu.ai.mit.edu)
* c-typeck.c (free_tree_list): New variable.
(digest_init): Set free_tree_list.
(process_init_constructor): Use add_double to do arithmetic with
double integers instead of using fold/build to to arithmetic in
type of array index. Use free_tree_list when available instead of
generating a new tree_list.
*** c-typeck.c.orig Thu Nov 26 12:30:00 1992
--- c-typeck.c Sat Apr 17 22:12:17 1993
*************** pedwarn_init (format, local, ofwhat)
*** 4521,4526 ****
--- 4521,4540 ----
pedwarn (format, buffer);
}
+ /* Keep a pointer to the last free TREE_LIST node as we digest an initializer,
+ so that we can reuse it. This is set in digest_init, and used in
+ process_init_constructor.
+
+ We will never keep more than one free TREE_LIST node here. This is for
+ two main reasons. First, we take elements off the old list and add them
+ to the new list one at a time, thus there should never be more than
+ one free TREE_LIST at a time, and thus even if there is, we will never
+ need more than one. Secondly, to avoid dangling pointers to freed obstacks,
+ we want to always ensure that we have either a pointer to a valid TREE_LIST
+ within the current initializer, or else a pointer to null. */
+
+ static tree free_tree_list = NULL_TREE;
+
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
*************** digest_init (type, init, tail, require_c
*** 4554,4566 ****
tree inside_init = init;
/* By default, assume we use one element from a list.
! We correct this later in the sole case where it is not true. */
if (tail)
{
old_tail_contents = *tail;
*tail = TREE_CHAIN (*tail);
}
if (init == error_mark_node)
return init;
--- 4568,4588 ----
tree inside_init = init;
/* By default, assume we use one element from a list.
! We correct this later in the cases where it is not true.
!
! Thus, we update TAIL now to point to the next element, and save the
! old value in OLD_TAIL_CONTENTS. If we didn't actually use the first
! element, then we will reset TAIL before proceeding. FREE_TREE_LIST
! is handled similarly. */
if (tail)
{
old_tail_contents = *tail;
*tail = TREE_CHAIN (*tail);
+ free_tree_list = old_tail_contents;
}
+ else
+ free_tree_list = 0;
if (init == error_mark_node)
return init;
*************** digest_init (type, init, tail, require_c
*** 4737,4742 ****
--- 4759,4765 ----
else if (tail != 0)
{
*tail = old_tail_contents;
+ free_tree_list = NULL_TREE;
result = process_init_constructor (type, NULL_TREE, tail,
require_constant,
constructor_constant, ofwhat);
*************** digest_init (type, init, tail, require_c
*** 4833,4838 ****
--- 4856,4862 ----
else if (tail != 0)
{
*tail = old_tail_contents;
+ free_tree_list = NULL_TREE;
return process_init_constructor (type, NULL_TREE, tail,
constructor_constant,
constructor_constant, ofwhat);
*************** process_init_constructor (type, init, el
*** 4917,4954 ****
if (TREE_CODE (type) == ARRAY_TYPE)
{
! tree min_index, max_index, current_index, members_index;
! tree bound_type;
! tree one;
/* These are non-zero only within a range initializer. */
tree start_index = 0, end_index = 0;
/* Within a range, this is the value for the elts in the range. */
tree range_val = 0;
/* If we have array bounds, set our bounds from that. Otherwise,
! we have a lower bound of zero and an unknown upper bound. Also
! set the type of the bounds; use "int" as default. */
if (TYPE_DOMAIN (type))
{
! min_index = members_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
- bound_type = TREE_TYPE (min_index);
}
else
{
! min_index = members_index = integer_zero_node;
max_index = 0;
- bound_type = integer_type_node;
}
! one = convert (bound_type, integer_one_node);
/* Don't leave the loop based on index if the next item has an explicit
index value that will override it. */
! for (current_index = min_index; tail != 0 || end_index;
! current_index = fold (build (PLUS_EXPR, bound_type,
! current_index, one)))
{
register tree next1 = 0;
--- 4941,4987 ----
if (TREE_CODE (type) == ARRAY_TYPE)
{
! tree min_index, max_index;
/* These are non-zero only within a range initializer. */
tree start_index = 0, end_index = 0;
/* Within a range, this is the value for the elts in the range. */
tree range_val = 0;
+ /* Do arithmetic using double integers, but don't use fold/build,
+ because these allocate a new tree object everytime they are called,
+ thus resulting in gcc using too much memory for large
+ initializers. */
+ union tree_node current_index_node, members_index_node;
+ tree current_index = ¤t_index_node;
+ tree members_index = &members_index_node;
+ TREE_TYPE (current_index) = integer_type_node;
+ TREE_TYPE (members_index) = integer_type_node;
/* If we have array bounds, set our bounds from that. Otherwise,
! we have a lower bound of zero and an unknown upper bound. */
if (TYPE_DOMAIN (type))
{
! min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
}
else
{
! min_index = integer_zero_node;
max_index = 0;
}
! TREE_INT_CST_LOW (members_index) = TREE_INT_CST_LOW (min_index);
! TREE_INT_CST_HIGH (members_index) = TREE_INT_CST_HIGH (min_index);
/* Don't leave the loop based on index if the next item has an explicit
index value that will override it. */
! for (TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (min_index),
! TREE_INT_CST_HIGH (current_index) = TREE_INT_CST_HIGH (min_index);
! tail != 0 || end_index;
! add_double (TREE_INT_CST_LOW (current_index),
! TREE_INT_CST_HIGH (current_index), 1, 0,
! &TREE_INT_CST_LOW (current_index),
! &TREE_INT_CST_HIGH (current_index)))
{
register tree next1 = 0;
*************** process_init_constructor (type, init, el
*** 5095,5114 ****
Make the list longer if necessary. */
while (! tree_int_cst_lt (current_index, members_index))
{
! members = tree_cons (NULL_TREE, NULL_TREE, members);
! members_index = fold (build (PLUS_EXPR, bound_type,
! members_index, one));
}
{
tree temp;
! tree idx;
temp = members;
! for (idx = fold (build (MINUS_EXPR, bound_type,
! members_index, one));
tree_int_cst_lt (current_index, idx);
! idx = fold (build (MINUS_EXPR, bound_type, idx, one)))
temp = TREE_CHAIN (temp);
TREE_VALUE (temp) = next1;
}
--- 5128,5165 ----
Make the list longer if necessary. */
while (! tree_int_cst_lt (current_index, members_index))
{
! if (free_tree_list)
! {
! TREE_CHAIN (free_tree_list) = members;
! TREE_PURPOSE (free_tree_list) = NULL_TREE;
! TREE_VALUE (free_tree_list) = NULL_TREE;
! members = free_tree_list;
! free_tree_list = NULL_TREE;
! }
! else
! members = tree_cons (NULL_TREE, NULL_TREE, members);
! add_double (TREE_INT_CST_LOW (members_index),
! TREE_INT_CST_HIGH (members_index), 1, 0,
! &TREE_INT_CST_LOW (members_index),
! &TREE_INT_CST_HIGH (members_index));
}
{
tree temp;
! union tree_node idx_node;
! tree idx = &idx_node;
! TREE_TYPE (idx) = integer_type_node;
temp = members;
! for (add_double (TREE_INT_CST_LOW (members_index),
! TREE_INT_CST_HIGH (members_index), -1, -1,
! &TREE_INT_CST_LOW (idx),
! &TREE_INT_CST_HIGH (idx));
tree_int_cst_lt (current_index, idx);
! add_double (TREE_INT_CST_LOW (idx),
! TREE_INT_CST_HIGH (idx), -1, -1,
! &TREE_INT_CST_LOW (idx),
! &TREE_INT_CST_HIGH (idx)))
temp = TREE_CHAIN (temp);
TREE_VALUE (temp) = next1;
}
*************** process_init_constructor (type, init, el
*** 5196,5202 ****
Make the list longer if necessary. */
while (i >= members_length)
{
! members = tree_cons (NULL_TREE, NULL_TREE, members);
members_length++;
}
{
--- 5247,5262 ----
Make the list longer if necessary. */
while (i >= members_length)
{
! if (free_tree_list)
! {
! TREE_CHAIN (free_tree_list) = members;
! TREE_PURPOSE (free_tree_list) = NULL_TREE;
! TREE_VALUE (free_tree_list) = NULL_TREE;
! members = free_tree_list;
! free_tree_list = NULL_TREE;
! }
! else
! members = tree_cons (NULL_TREE, NULL_TREE, members);
members_length++;
}
{
*************** process_init_constructor (type, init, el
*** 5284,5291 ****
else if (!TREE_CONSTANT (next1))
allconstant = 0;
else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
! allsimple = 0;
! members = tree_cons (field, next1, members);
}
/* If arguments were specified as a list, just remove the ones we used. */
--- 5344,5360 ----
else if (!TREE_CONSTANT (next1))
allconstant = 0;
else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
! allsimple = 0;
! if (free_tree_list)
! {
! TREE_CHAIN (free_tree_list) = members;
! TREE_PURPOSE (free_tree_list) = field;
! TREE_VALUE (free_tree_list) = next1;
! members = free_tree_list;
! free_tree_list = NULL_TREE;
! }
! else
! members = tree_cons (field, next1, members);
}
/* If arguments were specified as a list, just remove the ones we used. */
*************** process_init_constructor (type, init, el
*** 5316,5322 ****
if (erroneous)
return error_mark_node;
! result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members));
if (allconstant) TREE_CONSTANT (result) = 1;
if (allconstant && allsimple) TREE_STATIC (result) = 1;
return result;
--- 5385,5400 ----
if (erroneous)
return error_mark_node;
! if (elts)
! result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members));
! else
! {
! result = init;
! CONSTRUCTOR_ELTS (result) = nreverse (members);
! TREE_TYPE (result) = type;
! TREE_CONSTANT (result) = 0;
! TREE_STATIC (result) = 0;
! }
if (allconstant) TREE_CONSTANT (result) = 1;
if (allconstant && allsimple) TREE_STATIC (result) = 1;
return result;